﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading.Tasks;
using Hydra.Shell.Implementations;
using SLControlLibrary;
using Hydra.Shell.Enumerations;
using Hydra.Shell.Attributes;

namespace Hydra.Shell.Interfaces
{
    public class PackageExceptionEventArgs : EventArgs
    {
        public Exception Exception { get; set; }

        public PackageExceptionEventArgs()
        {
        }

        public PackageExceptionEventArgs(Exception ex)
        {
            this.Exception = ex;
        }
    }

    public class PackageLoadEventArgs : EventArgs
    {
        public IHydraPackage Package { get; set; }

        public PackageLoadEventArgs()
        {
        }

        public PackageLoadEventArgs(IHydraPackage Package)
        {
            this.Package = Package;
        }
    }

    public delegate void PackageLoadHandler(object sender, PackageLoadEventArgs e);
    public delegate void PackageExceptionHandler(object sender, PackageExceptionEventArgs e);

    public class PackageLoadOperation
    {
        public event PackageLoadHandler PackageLoaded;
        public event PackageExceptionHandler ExceptionOccured;
        public IHydraPackage Package { get; set; }
        public bool PackageAvailable { get; set; }
        public Exception Exception { get; set; }
        private UIThread uiThread;

        public PackageLoadOperation(UIThread uiThread)
        {
            this.uiThread = uiThread;
        }

        public PackageLoadOperation(Exception ex, UIThread uiThread)
        {
            this.Exception = ex;
            this.uiThread = uiThread;
        }

        public bool HasException
        {
            get
            {
                return this.Exception != null;
            }
        }

        public void SetLoaded(IHydraPackage Package)
        {
            this.Package = Package;
            this.PackageAvailable = true;

            PackageLoaded(this, new PackageLoadEventArgs(Package));
        }

        public void SetException(Exception ex)
        {
            ExceptionOccured(this, new PackageExceptionEventArgs(ex));
        }

        public void DelaySetLoaded(IHydraPackage package)
        {
            this.Package = package;
            this.PackageAvailable = true;

            uiThread.Run(() =>
            {
                PackageLoaded(this, new PackageLoadEventArgs(package));
            });
        }

        public void DelaySetException(Exception ex)
        {
            this.Exception = ex;

            uiThread.Run(() =>
            {
                ExceptionOccured(this, new PackageExceptionEventArgs(ex));
            });
        }
    }

    public delegate void OnRoutedEventHandler(int _event, RoutedEventArgs e);
    public delegate void OnShellPropertyChangeHandler(int propid, object var);

    [Guid("FD9DC8E3-2FFC-446D-8C50-99CA4A3D2D1C")]
    public interface IHydraShell
    {
        event OnRoutedEventHandler OnRoutedEvent;
        event OnShellPropertyChangeHandler OnShellPropertyChange;
        Dictionary<Guid, HydraPackageWrapper> LoadedPackages { get; }
        Dictionary<Guid, HydraServiceWrapper> LoadedServices { get; }
        Dictionary<Guid, IHydraEditorListItem> EditorsList { get; }
        int GetProperty(HydraProperties propid, out object pvar);
        bool IsPackageInstalled(Guid guidPackage);
        bool IsPackageLoaded(Guid guidPackage, out IHydraPackage ppPackage);
        PackageLoadOperation LoadPackage(Guid guidPackage);
        int SetProperty(HydraProperties propid, object var);
    }
}
